#ifndef B2_OBJECT_FACTORY
#define B2_OBJECT_FACTORY

#include "b2UserDataManager.h"
#include "b2UserData.h"
#include "b2d_common.h"
#include "Box2DMap.h"

#include "b2Polygon.h"
#include "b2Triangle.h"

class b2ObjectFactory {

	public:
			b2ObjectFactory(b2World* w, b2UserDataManager* udm);
			~b2ObjectFactory();
			
			t_symbol * last_s;
			long last_ac;
			t_atom * last_av;
		
			/* the function that begins the factory */
			void anything(t_symbol * s, long ac, t_atom * av); // everything comes in here

			void reset();
	
			void begin(long ac, t_atom * av);	// to start an object
			void end(long ac, t_atom * av);		// to end an object
			void destroy(long ac, t_atom *av);
		
	private:
	
		bool running; // are we in the process of creating an object?
	
		b2UserDataManager*	userDataManager;
		b2UserData*			userData;
		b2World* world;
		
		char* objectName;
		char* parentBody1;
		char* parentBody2;
		
		char* parentJoint1;
		char* parentJoint2;
		
		b2Body* body1;
		b2Body* body2;
		
		b2Joint* joint1;
		b2Joint* joint2;
		
		long userDataCount;
		t_atom userDataValue[1024];
		
		bool drawMe;
		
			
		void setParam(t_symbol * s, long ac, t_atom * av);
		void set();
	

		int currentObjectType;
	
		/* it it's a shape, what kind? */
		b2ShapeType currentShapeType;
		/* if it's a joint, what kind? */
		b2JointType currentJointType;
		
	
		/* the stuff we're working with at any given time */
		
		void initShapeDefs();	// init all of the default shape defs
		/* reuseable body definitions */
		b2BodyDef	bodyDef;

		/* reuseable shape definitions */
		b2CircleDef circleShapeDef;
		b2PolygonDef polyShapeDef;
		
		std::vector<b2Vec2> vertices;
				
		/* reuseable joint definitions */
		b2DistanceJointDef distanceJointDef;
		b2GearJointDef gearJointDef;
		b2MouseJointDef mouseJointDef;
		b2PrismaticJointDef prismaticJointDef;
		b2PulleyJointDef pulleyJointDef;
		b2RevoluteJointDef revoluteJointDef;
	
	
		void beginBody(long ac, t_atom * av);
		void beginCircle(long ac, t_atom * av);
		void beginPolygon(long ac, t_atom * av);
		void beginBox(long ac, t_atom * av);
		void beginRevoluteJoint(long ac, t_atom * av);
		void beginDistanceJoint(long ac, t_atom * av);
		void beginPrismaticJoint(long ac, t_atom * av);
		void beginPullyJoint(long ac, t_atom * av);
		void beginGearJoint(long ac, t_atom * av);
		void beginMouseJoint(long ac, t_atom * av);

		void endBody();
		void endCircle();
		void endPolygon();
		void endBox();
		void endRevoluteJoint();
		void endDistanceJoint();
		void endPrismaticJoint();
		void endPullyJoint();
		void endGearJoint();
		void endMouseJoint();

		void DecomposeConvexAndAddTo_MAX(b2Polygon* p, b2Body* bd, b2PolygonDef* prototype, 
											std::vector<b2PolygonShape*>& subPolyPointers); // pass by reference w/o const b/c we want to modify it

		
};

#endif

